
package com.eslab.osmonitor.providerDB;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Random;

import com.eolwral.osmonitor.R;

import android.app.Activity;
import android.content.Context;
import android.util.Log;

/**
 * 이 클래스는 SD card로 DB의 데이터를 exprots 하는 기능을 담당한다.
 * 포멧 형태는 GPX 표준 1.1 을 따른다.
 */
public class PowerModelWriter {
	
  private static final String TAG = "PowerModelWriter";
	
  private final Context context;	//UI 프로그레스 바를 종료 시키기위해 호출한 context를 가지고 있는다.
  private final FileUtils fileUtils;
  private Runnable onCompletion = null;	// 프로그레스 바의 완료 여부를 담당하는 쓰레드 이다.
  private boolean success = false;	// 성공적으로 파일이 생성 되었는지 여부를 판단한다.
  private int errorMessage = -1;
  private File directory = null;
  private File file = null;
  private PowerModel powerModel=null;
  private CWriter writer;
  
  // 생성자를 통해 필요한 객체 값을 모두 얻어온다.
  public PowerModelWriter(SaveInformationActivity context, PowerModel powerModel){
    this.fileUtils = new FileUtils();
    this.context = context;
    this.powerModel = powerModel;
    this.writer = new CWriter(); 
  }

  /**
   * 파일 생성 완료시 호출되어져 프로그레스 바를 종료하는 쓰레드이다..
   * @param 프로그레스 바를 종료하는 Runnable을 인자로 받는다.
   */
  public void setOnCompletion(Runnable onCompletion) {
    this.onCompletion = onCompletion;
  }

  /**
   * SD card에 생성 되어질 디렉토리 이름을 저장 한다.
   */
  public void setDirectory(File directory) {
    this.directory = directory;
  }

  public String getAbsolutePath() {
    return file.getAbsolutePath();
  }

  /**
   * 실제적으로 파일을 기록하는 쓰레드 이다.
   * non-blocking 상태에서 실행 되어 진다.
   */
  public void writeTrackAsync() {
    Thread t = new Thread() {
      @Override
      public void run() {
        writeTrack();
      }
    };
    t.start();
  }

  public void writeTrack() {
    // Open the input and output
    success = false;
 
      if (openFile()) {
        writeDocument();
      }
 
    /*너무 빨리 끝나기 때문에 계산 시간을 준다.*/
    try {
    	
		Thread.sleep(2500);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    finished();
  }

  public int getErrorMessage() {
    return errorMessage;
  }

  public boolean wasSuccess() {
    return success;
  }

  /*
   * 프로그레스 바를 실제적으로 죵료 하는 메소드 이다.
   */
  private void finished() {
    if (onCompletion != null) {
      runOnUiThread(onCompletion);
      return;
    }
  }

  /**
   * 프로그레스바의 내용을 출력하여 준다.
   */
  protected void runOnUiThread(Runnable runnable) {
    if (context instanceof Activity) {
      ((Activity) context).runOnUiThread(runnable);
    }
  }

  /**
   * 파일을 생성하는 모든 예외적인 상황을 담당하여 반드시 파일을 생성하여 준다.
   */
  protected boolean openFile() {
    if (!canWriteFile()) {
      return false;
    }

    // 중복된 이름이 있을경우 파일의 이름에 (1) , (2) 를 순서대로 증가 시켜 준다.
    String fileName = fileUtils.buildUniqueFileName(
        directory,"bravo","xml");
    if (fileName == null) {
      Log.e(TAG,
          "Unable to get a unique filename for " + fileName);
      return false;
    }

//  정상적인 파일 기록을 위해 데이터 처리 스트림을 데이터 싱크 스트림에게 넘겨준다. 트랙 정보와 같이
    Log.i(TAG, "Writing track to: " + fileName);
    try {
      writer.prepare(powerModel, newOutputStream(fileName));
    } catch (FileNotFoundException e) {
      Log.e(PowerModelWriter.TAG, "Failed to open output file.", e);
      errorMessage = R.string.io_write_failed;
      return false;
    }
    return true;
  }
  
  /**
   * 디렉토리의 여부를 체크한다음 없으면 디렉토리를 생성 한다.
   */
  protected boolean canWriteFile() {
    if (directory == null) {
      String dirName =
          fileUtils.buildExternalDirectoryPath(writer.getExtension());
      directory = newFile(dirName);
    }

    if (!fileUtils.isSdCardAvailable()) {
      Log.i(PowerModelWriter.TAG, "Could not find SD card.");
      errorMessage = R.string.io_no_external_storage_found;
      return false;
    }
    if (!fileUtils.ensureDirectoryExists(directory)) {
      Log.i(PowerModelWriter.TAG, "Could not create export directory.");
      errorMessage = R.string.io_create_dir_failed;
      return false;
    }

    return true;
  }

  /**
   * 파일 이름으로 데이터 처리 스트림을 생성하여 준다.
   */
  protected OutputStream newOutputStream(String fileName)
      throws FileNotFoundException {
    file = new File(directory, fileName);
    return new FileOutputStream(file);
  }

  /**
   * 해당 경로로 파일을 생성 한다.
   */
  protected File newFile(String path) {
    return new File(path);
  }

  /**
   * 실제적으로 GpxTrackWriter를 이용해서 파일에 내용을 기록하는 메소드 이다.
   */
  void writeDocument() {
    Log.d(PowerModelWriter.TAG, "Started writing power model.");
    writer.writePowerModel();
    writer.close();
    success = true;
    Log.d(PowerModelWriter.TAG, "Done writing power model.");
    errorMessage = R.string.io_write_finished;
  }
 
  
}
